using System;
using System.Collections.Generic;
using ECommerce.Web.DesignByContract;
using ECommerce.Web.Models;
using ECommerce.Web.NHibernate.Sessions;
using ECommerce.Web.Services.ShoppingSessions;
using NHibernate;

namespace ECommerce.Web.Commands
{
    public interface IChangeProductQuantitiesInBasketCommand
    {
        void Handle(ChangeProductQuantitiesInBasketMessage message);
    }

    public class ChangeProductQuantitiesInBasketMessage
    {
        public ChangeProductQuantitiesInBasketMessage()
        {
            ProductQuantityMessages = new List<ProductQuantityMessage>();
        }

        public int BasketId { get; set; }
        public IList<ProductQuantityMessage> ProductQuantityMessages { get; set; }

        public class ProductQuantityMessage
        {
            public int ProductId { get; set; }
            public int Quantity { get; set; }
        }
    }

    public class ChangeProductQuantitiesInBasketCommand : IChangeProductQuantitiesInBasketCommand
    {
        private readonly IShoppingSession shoppingSession;

        public ChangeProductQuantitiesInBasketCommand(IShoppingSession shoppingSession)
        {
            this.shoppingSession = shoppingSession;
        }

        public void Handle(ChangeProductQuantitiesInBasketMessage message)
        {
            Contract.Require(message.BasketId != default(int), "BasketId should not be default value.");
            Contract.Require(message.ProductQuantityMessages.Count > 0, "Message should contain items.");

            Guid shopperToken = this.shoppingSession.GetShopperToken();

            ISession session = SessionSource.Current.GetSession();

            using (ITransaction transaction = session.BeginTransaction())
            {
                var shopper = session.FindById<IShopperWithBasket>(shopperToken);

                foreach (ChangeProductQuantitiesInBasketMessage.ProductQuantityMessage productQuantityMessage in message.ProductQuantityMessages)
                {
                    var product = new Product() { Id = productQuantityMessage.ProductId };

                    shopper.ChangeProductQuantityInBasket(product, productQuantityMessage.Quantity);
                }

                transaction.Commit();
            }
        }
    }
}